default_platform(:ios)

platform :ios do

  before_all do
    begin
        xcodes(version: "16.0", select_for_current_build_only: true)
    rescue => ex
        UI.error("Failed when switching to Xcode version: #{ex}")
    end
  end

  desc "Switch to Beta environment"
  lane :to_beta do
    Action.sh("ruby ../script/to_beta.rb")
  end

  desc "Run tests."
  lane :tests do
    sdk_tests
  end

  lane :sdk_tests do
    swift_version = ENV["SWIFT_VERSION"] || "4.2"
    run_tests(
        workspace: "LineSDK.xcworkspace",
        devices: ["iPhone 16"],
        scheme: "LineSDK",
        xcargs: "SWIFT_VERSION=#{swift_version}"
    )
    
    run_tests(
        workspace: "LineSDK.xcworkspace",
        devices: ["iPhone 16"],
        scheme: "LineSDKObjC",
        xcargs: "SWIFT_VERSION=#{swift_version}"
    )
  end

  lane :sample_tests do
    run_tests(
        workspace: "LineSDK.xcworkspace",
        devices: ["iPhone 16"],
        scheme: "LineSDKSample"
    )
  end

  desc "Lint to check dependency manager compatibility."
  lane :lint do
    lint_spm
    lint_pod
  end

  lane :lint_pod do
    swift_version = ENV["SWIFT_VERSION"] || "4.2"
    Action.sh("bundle exec pod lib lint ../LineSDKSwift.podspec --swift-version=#{swift_version}")
  end

  lane :lint_spm do
    sdk_path = `xcrun --sdk iphonesimulator --show-sdk-path`.strip
    swiftc_flags = [
        "-sdk", sdk_path,
        "-target", "arm64-apple-ios18.0-simulator"
    ].map { |flag| "-Xswiftc #{flag}" }
    cc_flags = [
        "-isysroot", sdk_path
    ].map { |flag| "-Xcc #{flag}" }

    sh("swift build #{swiftc_flags.join(' ')} #{cc_flags.join(' ')}")
  end

  desc "Release a new version."
  lane :release do |options|
    target_version = options[:version]
    raise "The version is missed. Use `fastlane release version:{version_number}`.`" if target_version.nil?

    ensure_git_branch
    ensure_git_status_clean

    tests
    lint

    increment_build_number(
        build_number: number_of_commits,
        xcodeproj: "LineSDK/LineSDK.xcodeproj"
    )
    increment_version_number(
        version_number: target_version,
        xcodeproj: "LineSDK/LineSDK.xcodeproj"
    )

    bump_constant_version(version: target_version)
    bump_reference_top_version(version: target_version)
    version_bump_podspec(path: "LineSDKSwift.podspec", version_number: target_version)
    
    release_content = read_changelog(excluded_markdown_elements: [])
    change_log(version: target_version)

    git_commit_all(message: "Bump version to #{target_version}")
    Actions.sh("git tag -u #{ENV["GPG_KEY_ID"]} #{target_version} -m ''")

    binary_frameworks = xcframework(version: target_version)
    
    push_to_git_remote
    set_github_release(
      repository_name: "line/line-sdk-ios-swift",
      api_token: ENV["GITHUB_TOKEN"],
      name: target_version,
      tag_name: target_version,
      upload_assets: binary_frameworks,
      description: release_content
    )

    pod_push
  end

  desc "Generate documentation"
  lane :doc do
    copyright = "jazzy --copyright '© " + Time.new.year.to_s + " [LY Corporation.](https://line.me) All rights reserved.'"
    Actions.sh(copyright)
  end

  desc "Generate documentation for internal usage"
  lane :doc_internal do
    jazzy(config: ".jazzy-internal.yaml")
  end

  lane :change_log do |options|
    target_version = options[:version]
    raise "The version is missed. You need to specify a version parameter." if target_version.nil?
    stamp_changelog(section_identifier: target_version, git_tag: target_version, stamp_datetime_format: "%F")
  end

  lane :bump_constant_version do |options|
    target_version = options[:version]
    replacing = "public static let SDKVersion = \"#{target_version}\""
    regex = "public static let SDKVersion = .*"
    constant_file = "../LineSDK/LineSDK/Utils/Constant.swift"
    Action.sh("sed -e 's/#{regex}/#{replacing}/g' #{constant_file} | tee #{constant_file}")
  end

  lane :bump_reference_top_version do |options|
    target_version = options[:version]
    target_version_to_minor = target_version.split(".")[0...-1].join(".")
    lines = File.readlines("../REFERENCETOP.md")
    lines[0] = "# LINE SDK v#{target_version_to_minor} for iOS Swift\n"
    File.open("../REFERENCETOP.md", "w") { |f| f.write(lines.join) }
  end

  desc "Create binary frameworks with the `xcframework` format under the `build/` folder."
  lane :xcframework do |options|
    target_version = options[:version]
    output_path = "build"

    FileUtils.rm_rf "../#{output_path}"
    
    artifact_paths = []

    create_xcframework(
      workspace: "LineSDK.xcworkspace", 
      scheme: "LineSDK", 
      destinations: ['iOS'],
      enable_bitcode: false,
      include_debug_symbols: true,
      xcframework_output_directory: output_path
    )
    unless is_ci
      Actions.sh("codesign --timestamp -v --sign 'Apple Distribution: LINE Corporation (VUTU7AKEUR)' ../#{output_path}/LineSDK.xcframework")
    end
    artifact_paths.push(ENV["XCFRAMEWORK_OUTPUT_PATH"])
    
    create_xcframework(
      workspace: "LineSDK.xcworkspace", 
      scheme: "LineSDKObjCBinary", 
      product_name: "LineSDKObjC", 
      destinations: ['iOS'], 
      enable_bitcode: false,
      include_debug_symbols: true,
      xcframework_output_directory: output_path
    )
    unless is_ci
      Actions.sh("codesign --timestamp -v --sign 'Apple Distribution: LINE Corporation (VUTU7AKEUR)' ../#{output_path}/LineSDKObjC.xcframework")
    end
    artifact_paths.push(ENV["XCFRAMEWORK_OUTPUT_PATH"])

    zipped_files = []
    artifact_paths.each do |path|
      basename = File.basename(path, ".xcframework")
      zipped_files << zip(path: path, output_path: "#{output_path}/#{basename}-#{target_version}.zip")
    end
    zipped_files
  end
end
